{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8ac0072d-0974-4785-b9ed-d6e3f5c18bff",
   "metadata": {},
   "source": [
    "# Module 4 - Exploring Video Generation with **Amazon Nova Reel**\n",
    "\n",
    "---\n",
    "\n",
    "In this notebook, we'll explore the capabilities of Amazon Nova Reel, a powerful video generation model.\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af79685b-eb7d-4966-8c31-0973ae4f1bcd",
   "metadata": {},
   "source": [
    "### Introduction\n",
    "\n",
    "In this notebook, you'll explore Amazon Nova Reel, a cutting-edge video generation model that creates high-quality, studio-grade videos from text or a combination of text and images. Nova Reel enables text-to-video and image-and-text to video generation, producing up to two-minute videos in smooth 6-second segments at 1280x720 resolution and 24 FPS. Whether you're creating product showcases, dynamic marketing content, or storytelling animations, Nova Reel empowers businesses to generate compelling, visually rich video content with minimal effort—unlocking faster creative cycles and more personalized customer engagement.\n",
    "\n",
    "Following the use case for Octank Dog Food for Nova Canvas (in the previous notebook lab), we'll create short video ads for a dog food company using two main features:\n",
    "\n",
    "1. **Text-to-Video**: Generate a 6-second video from a text prompt.\n",
    "2. **Image-to-Video**: Generate a 6-second video using both text and an input image.\n",
    "\n",
    "### Prerequisites\n",
    "\n",
    "**If you are running AWS-facilitated event**, all other pre-requisites are satisfied and you can go to the next section.\n",
    "\n",
    "**If you are running this notebook as a self-paced lab**, then please make sure that:\n",
    "\n",
    "1. Your AWS execution role has the necessary permissions to write and read from the dedicated S3 location.\n",
    "2. The following minimum permissions are configured:\n",
    "   - `bedrock:InvokeModel`\n",
    "   - `s3:PutObject`\n",
    "   - `s3:GetObject`\n",
    "3. For better tracking of video generation jobs, we recommend adding these permissions:\n",
    "   - `bedrock:GetAsyncInvoke`\n",
    "   - `bedrock:ListAsyncInvokes`\n",
    "\n",
    "**Note:** Ensure that these permissions are properly scoped to the specific S3 buckets and prefixes you intend to use for security best practices."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a03a2f8-58f8-40bd-92a2-c7d2ad033082",
   "metadata": {},
   "source": [
    "## 1. Setup\n",
    "\n",
    "### 1.1 Import Libraries and Init Clients\n",
    "\n",
    "First, let's import the required libraries and set up our Bedrock client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c039c8ec-748f-4acc-adb1-c1cecb5fb6a6",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import time\n",
    "import boto3\n",
    "import json\n",
    "import base64\n",
    "from botocore.exceptions import ClientError\n",
    "\n",
    "account_id = boto3.client('sts').get_caller_identity().get('Account')\n",
    "\n",
    "bedrock_runtime = boto3.client('bedrock-runtime')\n",
    "s3_bucket = f\"video-bucket-{account_id}\"\n",
    "local_output_folder = \"output\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0549046-7ced-4bce-8af5-d100b5ae5b87",
   "metadata": {},
   "source": [
    "### 1.2 Create an S3 Bucket for Storing Results of Video Generation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "750dc879-ee84-48bc-beab-f3c895e61a9f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create S3 bucket if s3_bucket doesn't exist\n",
    "def create_bucket_if_not_exists(bucket_name, region=\"us-east-1\"):\n",
    "    \"\"\"\n",
    "    Create an S3 bucket if it doesn't exist.\n",
    "    \n",
    "    :param bucket_name: Name of the bucket\n",
    "    :param region: Region to create the bucket in, e.g., 'us-east-1'\n",
    "    :return: True if bucket was created or already exists, False on error\n",
    "    \"\"\"\n",
    "    s3_client = boto3.client('s3', region_name=region)\n",
    "\n",
    "    try:\n",
    "        s3_client.head_bucket(Bucket=bucket_name)\n",
    "        print(f\"Bucket '{bucket_name}' already exists.\")\n",
    "        return True\n",
    "    except ClientError as e:\n",
    "        error_code = e.response['Error']['Code']\n",
    "        if error_code == '404':\n",
    "            try:\n",
    "                if region == \"us-east-1\":\n",
    "                    s3_client.create_bucket(Bucket=bucket_name)\n",
    "                else:\n",
    "                    location = {'LocationConstraint': region}\n",
    "                    s3_client.create_bucket(Bucket=bucket_name,\n",
    "                                            CreateBucketConfiguration=location)\n",
    "                print(f\"Bucket '{bucket_name}' created successfully.\")\n",
    "                return True\n",
    "            except ClientError as e:\n",
    "                print(f\"Couldn't create bucket '{bucket_name}'. Error: {e}\")\n",
    "                return False\n",
    "        else:\n",
    "            print(f\"Error checking bucket '{bucket_name}'. Error: {e}\")\n",
    "            return False\n",
    "        \n",
    "create_bucket_if_not_exists(s3_bucket)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c992d7b-f55e-49d8-bf09-a81ee950142c",
   "metadata": {},
   "source": [
    "## 2. Use Case Implementation: Text to Video\n",
    "\n",
    "#### Scenario\n",
    "\n",
    "Octank, a premium dog food company, is launching a new line of gourmet dog food. The marketing team wants to create engaging short video ads to showcase their product's quality and appeal. They decide to leverage Amazon Nova Reel's text-to-video generation capabilities to create a captivating 6-second video clip that highlights their product.\n",
    "\n",
    "#### What are the key parameters?\n",
    "\n",
    "1. **text**: This is the prompt that describes the video you want to generate. It should be detailed and descriptive to guide the model in creating the desired output.\n",
    "\n",
    "2. **durationSeconds**: This parameter sets the length of the generated video. Currently, Nova Reel supports 6-second videos.\n",
    "\n",
    "3. **fps**: Frames per second of the output video. The current supported value is 24 fps.\n",
    "\n",
    "4. **dimension**: This defines the resolution of the output video. The current supported dimension is 1280x720 pixels.\n",
    "\n",
    "5. **seed**: An optional parameter that initializes the generation process. Using the same seed with identical parameters will produce the same video, allowing for reproducibility.\n",
    "\n",
    "Let's generate our first video using these parameters:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2686121-8bec-45af-98b3-1bda3f5d0bb5",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "prompt = \"\"\"\n",
    "Close-up shot of a shiny stainless steel bowl filled with gourmet dog food on a clean kitchen tile floor. Soft natural light from a nearby window highlights text textures. Slow camera zoom in, gradually revealing more detail of the appetizing meal. 4k resolution, cinematic quality.\n",
    "\"\"\"\n",
    "\n",
    "seed_num = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc0b9fa5-0d76-4dc4-94f6-6606b8b3cf10",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def generate_video_from_text(prompt, s3_output_path):\n",
    "    model_input = {\n",
    "        \"taskType\": \"TEXT_VIDEO\",\n",
    "        \"textToVideoParams\": {\n",
    "            \"text\": prompt\n",
    "            },\n",
    "        \"videoGenerationConfig\": {\n",
    "            \"durationSeconds\": 6, \n",
    "            \"fps\": 24,\n",
    "            \"dimension\": \"1280x720\",\n",
    "            \"seed\": seed_num #random.randint(0, 2147483646),\n",
    "        },\n",
    "    }\n",
    "    response = bedrock_runtime.start_async_invoke(\n",
    "        modelId=\"amazon.nova-reel-v1:0\",\n",
    "        modelInput=model_input,\n",
    "        outputDataConfig={\"s3OutputDataConfig\": {\"s3Uri\": f\"s3://{s3_output_path}\"}},\n",
    "    )\n",
    "\n",
    "    return response['invocationArn']\n",
    "\n",
    "\n",
    "invocation_arn = generate_video_from_text(prompt, s3_bucket)\n",
    "print(f\"Video generation job started. Invocation ARN: {invocation_arn}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96e412f1-fe10-4bef-a486-9c8c1160d512",
   "metadata": {},
   "source": [
    "### 2.1 Checking Job Progress\n",
    "\n",
    "To check the progress of our video generation jobs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "303960ef-401b-4c08-a316-5a9197f44656",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Waiting for video generation job to complete: \", end='')\n",
    "\n",
    "while True:\n",
    "    response = bedrock_runtime.get_async_invoke(invocationArn=invocation_arn)\n",
    "    if response[\"status\"].upper() == \"COMPLETED\":\n",
    "        print(\" done.\")\n",
    "        break\n",
    "    print('█', end='', flush=True)\n",
    "    time.sleep(5)\n",
    "\n",
    "print(\"Job completed successfully with invocation ARN:\", invocation_arn)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ec5d83d-0d4a-43b6-b29e-c03057fe8263",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Note:</b> On average, it takes about 3-4 mins to generate the video.\n",
    "</div>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27482a3e-7fb2-4bc3-8a72-2e8c2dfeb09c",
   "metadata": {},
   "source": [
    "### 2.2 Download the Generated Video\n",
    "\n",
    "Once the job is **completed**, we can download the generated video to local\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "acb333e5-def1-48ef-b3d0-a3eac8cae3af",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def download_video_for_invocation_arn(invocation_arn, bucket_name, destination_folder):\n",
    "    \"\"\"\n",
    "    This function downloads the video file for the given invocation ARN.\n",
    "    \"\"\"\n",
    "    invocation_id = invocation_arn.split(\"/\")[-1]\n",
    "\n",
    "    # Create the local file path\n",
    "    file_name = f\"{invocation_id}.mp4\"\n",
    "\n",
    "    local_file_path = os.path.join(destination_folder, file_name)\n",
    "\n",
    "    # Ensure the output folder exists\n",
    "    os.makedirs(destination_folder, exist_ok=True)\n",
    "\n",
    "    # Create an S3 client\n",
    "    s3 = boto3.client(\"s3\")\n",
    "\n",
    "    # List objects in the specified folder\n",
    "    response = s3.list_objects_v2(Bucket=bucket_name, Prefix=invocation_id)\n",
    "\n",
    "    # Find the first MP4 file and download it.\n",
    "    for obj in response.get(\"Contents\", []):\n",
    "        object_key = obj[\"Key\"]\n",
    "        if object_key.endswith(\".mp4\"):\n",
    "            print(f\"\"\"Downloading \"{object_key}\"...\"\"\")\n",
    "            s3.download_file(bucket_name, object_key, local_file_path)\n",
    "            print(f\"Downloaded to {local_file_path}\")\n",
    "            return local_file_path\n",
    "\n",
    "    # If we reach this point, no MP4 file was found.\n",
    "    print(f\"Problem: No MP4 file was found in S3 at {bucket_name}/{invocation_id}\")\n",
    "\n",
    "    return local_file_path\n",
    "    \n",
    "video_path = download_video_for_invocation_arn(invocation_arn, s3_bucket, local_output_folder)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b819746-cabd-4646-b5c5-adab4cd81ce3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Preiview generated video\n",
    "from IPython.display import Video\n",
    "\n",
    "Video(video_path, width=900)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20841a33-d863-45ad-8888-27a4871129b6",
   "metadata": {},
   "source": [
    "## 3. Use Case Implementation: Image to Video"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5a02674-f77c-4593-a5b5-38b6eed14900",
   "metadata": {},
   "source": [
    "#### Scenario\n",
    "\n",
    "Now that Octank has a finalized design for their dog food package, they want to create a video that showcases the product from different angles. They decide to use Nova Reel's image-to-video feature to generate a 6-second video of the product rotating clockwise on a kitchen countertop\n",
    "\n",
    "#### What are the key parameters?\n",
    "- **text**: This is the prompt that describes the desired video animation.\n",
    "- **image**: The base64-encoded image that serves as the reference for the video.\n",
    "- **durationSeconds**: The length of the generated video (6 seconds).\n",
    "- **fps**: Frames per second of the output video (24 fps).\n",
    "- **dimension**: The resolution of the output video (1280x720 pixels).\n",
    "- **seed**: An optional parameter for reproducibility.\n",
    "\n",
    "Let's generate our video using these parameters:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "231e5cf3-6466-4a14-bae2-f3487175174e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Define function to convert image to base64 object\n",
    "def image_to_base64(image_path):\n",
    "    with open(image_path, \"rb\") as image_file:\n",
    "        return base64.b64encode(image_file.read()).decode('utf-8')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1fe0b41a-ffad-476d-8cd5-b358f25ff083",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Customized parameters\n",
    "image_path = \"images/video_input.png\"\n",
    "base64_image = image_to_base64(image_path)\n",
    "\n",
    "prompt = \"Camera slowly rotates in clockwise direction around the dog food package on a kitchen countertop\"\n",
    "\n",
    "seed_num = 0  # Change this for different results\n",
    "\n",
    "image_format = image_path.split(\".\")[-1]\n",
    "if image_format not in [\"png\", \"jpeg\"]:\n",
    "    assert print(\"Only .png or .jpeg supported\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7dfcca00-0c6f-4bda-802c-3b722bd2c84e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Preview image to generate video from\n",
    "from IPython.display import Image\n",
    "\n",
    "Image(image_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6ea67d0-3c04-47b9-8fef-9bda2849bb5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_video_from_image(prompt, base64_image, s3_output_path, image_format):\n",
    "    model_input = {\n",
    "        \"taskType\": \"TEXT_VIDEO\",\n",
    "        \"textToVideoParams\": {\n",
    "            \"text\": prompt,\n",
    "            \"images\": [\n",
    "                {\n",
    "                    \"format\": image_format,  # May be \"png\" or \"jpeg\"\n",
    "                    \"source\": {\n",
    "                        \"bytes\": base64_image\n",
    "                    }\n",
    "                }\n",
    "            ]\n",
    "        },\n",
    "        \"videoGenerationConfig\": {\n",
    "            \"durationSeconds\": 6, \n",
    "            \"fps\": 24,\n",
    "            \"dimension\": \"1280x720\",\n",
    "            \"seed\": seed_num\n",
    "        },\n",
    "    }\n",
    "    response = bedrock_runtime.start_async_invoke(\n",
    "        modelId=\"amazon.nova-reel-v1:0\",\n",
    "        modelInput=model_input,\n",
    "        outputDataConfig={\"s3OutputDataConfig\": {\"s3Uri\": f\"s3://{s3_output_path}\"}},\n",
    "    )\n",
    "\n",
    "    return response['invocationArn']\n",
    "\n",
    "invocation_arn = generate_video_from_image(prompt, base64_image, s3_bucket, image_format)\n",
    "print(f\"Video generation job started. Invocation ARN: {invocation_arn}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ee39d44-1b76-44d5-b825-d01e50a11ef7",
   "metadata": {},
   "source": [
    "### 3.1 Check status and download the generated video"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99e146ba-51d8-4141-910a-7b7255fa1f82",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Waiting for video generation job to complete: \", end='')\n",
    "\n",
    "while True:\n",
    "    response = bedrock_runtime.get_async_invoke(invocationArn=invocation_arn)\n",
    "    if response[\"status\"].upper() == \"COMPLETED\":\n",
    "        print(\" done.\")\n",
    "        break\n",
    "    print('█', end='', flush=True)\n",
    "    time.sleep(5)\n",
    "\n",
    "print(\"Job completed successfully with invocation ARN:\", invocation_arn)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e858bb25-8260-45da-b8c6-8c236ea26155",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-block alert-info\">\n",
    "<b>Note:</b> On average, it takes about 3-4 mins to generate the video.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebbe2776-30ef-4be1-98b7-488cf7c4f7f4",
   "metadata": {},
   "source": [
    "### 3.2 Download the Generated Video"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e7f2e97-6bb4-421b-bce9-0ea803ec7a89",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Once the job is complete, download the video\n",
    "video_path = video_path = download_video_for_invocation_arn(invocation_arn, s3_bucket, local_output_folder)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64c2fdcb-885b-4012-9d84-517c34861437",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Preiview generated video\n",
    "from IPython.display import Video\n",
    "\n",
    "Video(video_path, width=900)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "411afc8b-869e-463d-a592-bee7ffb5090c",
   "metadata": {},
   "source": [
    "## 4. Conclusion and Next Steps\n",
    "\n",
    "In this notebook, we've demonstrated how to use Amazon Nova Reel to generate short video ads for a dog food company. We explored both text-to-video and image-to-video generation capabilities, providing a powerful tool for creating engaging visual content.\n",
    "\n",
    "### Next Steps\n",
    "\n",
    "Please return to the workshop instructions page and proceed to your next workshop module, if needed."
   ]
  }
 ],
 "metadata": {
  "availableInstances": [
   {
    "_defaultOrder": 0,
    "_isFastLaunch": true,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 4,
    "name": "ml.t3.medium",
    "vcpuNum": 2
   },
   {
    "_defaultOrder": 1,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 8,
    "name": "ml.t3.large",
    "vcpuNum": 2
   },
   {
    "_defaultOrder": 2,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.t3.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 3,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.t3.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 4,
    "_isFastLaunch": true,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 8,
    "name": "ml.m5.large",
    "vcpuNum": 2
   },
   {
    "_defaultOrder": 5,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.m5.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 6,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.m5.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 7,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 64,
    "name": "ml.m5.4xlarge",
    "vcpuNum": 16
   },
   {
    "_defaultOrder": 8,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 128,
    "name": "ml.m5.8xlarge",
    "vcpuNum": 32
   },
   {
    "_defaultOrder": 9,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 192,
    "name": "ml.m5.12xlarge",
    "vcpuNum": 48
   },
   {
    "_defaultOrder": 10,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 256,
    "name": "ml.m5.16xlarge",
    "vcpuNum": 64
   },
   {
    "_defaultOrder": 11,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 384,
    "name": "ml.m5.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 12,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 8,
    "name": "ml.m5d.large",
    "vcpuNum": 2
   },
   {
    "_defaultOrder": 13,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.m5d.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 14,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.m5d.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 15,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 64,
    "name": "ml.m5d.4xlarge",
    "vcpuNum": 16
   },
   {
    "_defaultOrder": 16,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 128,
    "name": "ml.m5d.8xlarge",
    "vcpuNum": 32
   },
   {
    "_defaultOrder": 17,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 192,
    "name": "ml.m5d.12xlarge",
    "vcpuNum": 48
   },
   {
    "_defaultOrder": 18,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 256,
    "name": "ml.m5d.16xlarge",
    "vcpuNum": 64
   },
   {
    "_defaultOrder": 19,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 384,
    "name": "ml.m5d.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 20,
    "_isFastLaunch": false,
    "category": "General purpose",
    "gpuNum": 0,
    "hideHardwareSpecs": true,
    "memoryGiB": 0,
    "name": "ml.geospatial.interactive",
    "supportedImageNames": [
     "sagemaker-geospatial-v1-0"
    ],
    "vcpuNum": 0
   },
   {
    "_defaultOrder": 21,
    "_isFastLaunch": true,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 4,
    "name": "ml.c5.large",
    "vcpuNum": 2
   },
   {
    "_defaultOrder": 22,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 8,
    "name": "ml.c5.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 23,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.c5.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 24,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.c5.4xlarge",
    "vcpuNum": 16
   },
   {
    "_defaultOrder": 25,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 72,
    "name": "ml.c5.9xlarge",
    "vcpuNum": 36
   },
   {
    "_defaultOrder": 26,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 96,
    "name": "ml.c5.12xlarge",
    "vcpuNum": 48
   },
   {
    "_defaultOrder": 27,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 144,
    "name": "ml.c5.18xlarge",
    "vcpuNum": 72
   },
   {
    "_defaultOrder": 28,
    "_isFastLaunch": false,
    "category": "Compute optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 192,
    "name": "ml.c5.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 29,
    "_isFastLaunch": true,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.g4dn.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 30,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.g4dn.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 31,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 64,
    "name": "ml.g4dn.4xlarge",
    "vcpuNum": 16
   },
   {
    "_defaultOrder": 32,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 128,
    "name": "ml.g4dn.8xlarge",
    "vcpuNum": 32
   },
   {
    "_defaultOrder": 33,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 4,
    "hideHardwareSpecs": false,
    "memoryGiB": 192,
    "name": "ml.g4dn.12xlarge",
    "vcpuNum": 48
   },
   {
    "_defaultOrder": 34,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 256,
    "name": "ml.g4dn.16xlarge",
    "vcpuNum": 64
   },
   {
    "_defaultOrder": 35,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 61,
    "name": "ml.p3.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 36,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 4,
    "hideHardwareSpecs": false,
    "memoryGiB": 244,
    "name": "ml.p3.8xlarge",
    "vcpuNum": 32
   },
   {
    "_defaultOrder": 37,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 8,
    "hideHardwareSpecs": false,
    "memoryGiB": 488,
    "name": "ml.p3.16xlarge",
    "vcpuNum": 64
   },
   {
    "_defaultOrder": 38,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 8,
    "hideHardwareSpecs": false,
    "memoryGiB": 768,
    "name": "ml.p3dn.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 39,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.r5.large",
    "vcpuNum": 2
   },
   {
    "_defaultOrder": 40,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.r5.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 41,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 64,
    "name": "ml.r5.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 42,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 128,
    "name": "ml.r5.4xlarge",
    "vcpuNum": 16
   },
   {
    "_defaultOrder": 43,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 256,
    "name": "ml.r5.8xlarge",
    "vcpuNum": 32
   },
   {
    "_defaultOrder": 44,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 384,
    "name": "ml.r5.12xlarge",
    "vcpuNum": 48
   },
   {
    "_defaultOrder": 45,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 512,
    "name": "ml.r5.16xlarge",
    "vcpuNum": 64
   },
   {
    "_defaultOrder": 46,
    "_isFastLaunch": false,
    "category": "Memory Optimized",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 768,
    "name": "ml.r5.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 47,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 16,
    "name": "ml.g5.xlarge",
    "vcpuNum": 4
   },
   {
    "_defaultOrder": 48,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.g5.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 49,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 64,
    "name": "ml.g5.4xlarge",
    "vcpuNum": 16
   },
   {
    "_defaultOrder": 50,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 128,
    "name": "ml.g5.8xlarge",
    "vcpuNum": 32
   },
   {
    "_defaultOrder": 51,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 1,
    "hideHardwareSpecs": false,
    "memoryGiB": 256,
    "name": "ml.g5.16xlarge",
    "vcpuNum": 64
   },
   {
    "_defaultOrder": 52,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 4,
    "hideHardwareSpecs": false,
    "memoryGiB": 192,
    "name": "ml.g5.12xlarge",
    "vcpuNum": 48
   },
   {
    "_defaultOrder": 53,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 4,
    "hideHardwareSpecs": false,
    "memoryGiB": 384,
    "name": "ml.g5.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 54,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 8,
    "hideHardwareSpecs": false,
    "memoryGiB": 768,
    "name": "ml.g5.48xlarge",
    "vcpuNum": 192
   },
   {
    "_defaultOrder": 55,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 8,
    "hideHardwareSpecs": false,
    "memoryGiB": 1152,
    "name": "ml.p4d.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 56,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 8,
    "hideHardwareSpecs": false,
    "memoryGiB": 1152,
    "name": "ml.p4de.24xlarge",
    "vcpuNum": 96
   },
   {
    "_defaultOrder": 57,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 32,
    "name": "ml.trn1.2xlarge",
    "vcpuNum": 8
   },
   {
    "_defaultOrder": 58,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 512,
    "name": "ml.trn1.32xlarge",
    "vcpuNum": 128
   },
   {
    "_defaultOrder": 59,
    "_isFastLaunch": false,
    "category": "Accelerated computing",
    "gpuNum": 0,
    "hideHardwareSpecs": false,
    "memoryGiB": 512,
    "name": "ml.trn1n.32xlarge",
    "vcpuNum": 128
   }
  ],
  "instance_type": "ml.t3.medium",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
